
import { Node, Vec3 } from "cc";

export interface IRuningGuide {
    config: IGuideConfig;
    //是否在前置步骤阶段
    isInPreStep: boolean;
    stepIdx: number;
    //当前stepIdx需要执行的所有步骤
    steps: IGuideStep[];
}

export interface IGuideConfig {
    id: number;
    name: string;
    //是否执行引导，可配置局部跳过
    isRunGuide: boolean;
    //是否需要本地存储，如果缓存了游戏启动时就会自动运行引导，不再判断触发条件
    isLocalSave: boolean;
    //执行顺序，排队or立刻执行
    exeSequence: GuideExeSequence;
    //前置步骤Map，不会进行保存
    preStepsMap?: Map<number, IGuideStep[]>;
    //正式执行步骤
    steps: IGuideStep[];
    onComplete?: Function;
}

export interface IGuideStep {
    //id不用手动设置，会自动赋值，所以设置为可空
    id?: number;
    //备注，debug用
    desc: string;
    //前置引导步骤索引，用于在退出中断时，重新进行这一步之前可能需要一些前置步骤
    preSteps?: number[];
    //详细命令
    command: IGuideCommand;
    //是否需要同步至服务端
    isSaveServer?: boolean;
    //延迟执行
    delay?: number;
    onInit?: Function;
    onStart?: Function;
    onEnd?: Function;
}

export interface IGuideCommand {
    cmd: GuideCmd;
    args?: any
}

export enum GuideCmd {
    WeakGuide,
    ForceGuide,
}

export enum GuideExeSequence {
    //排队，一个完下一个
    Queue,
    //立刻执行
    Sync,
}


export interface IGuideMediator {
    run(guideId: number, stepId: number, args?: any);
    update(dt: number);
    complete();
}

export enum GuideWeakClickType {
    //节点事件
    Node,
    //全局事件
    Global,
}

export interface IGuideWeakArgs {
    locator: string;
    waitTime: number;
    clickType: GuideWeakClickType;
    //一直重置搜索节点
    alwaysSearchNode?: boolean;
    loop?: number;
    condition?: () => boolean;
}

export enum GuideForceType {
    Click,
    Move,
}

export interface IGuideForceArgs {
    type: GuideForceType
}

export interface IGuideForceClickArgs extends IGuideForceArgs {
    locators: () => string[];
    stepCondition?: () => boolean;
    tips?: IGuideTips;
}

export interface IGuideForceMoveArgs extends IGuideForceArgs {
    locators: string[];
    moveTime: number;
    stepCondition?: (nodes: Node[]) => boolean;
}

export interface IGuideTips {
    getTips: () => string;
    getWorldPos: (nodePos: Vec3) => Vec3;
}